﻿using Arction.Wpf.BindableCharting.SeriesXY;
using Arction.Wpf.BindableCharting.Views.ViewXY;
using Prism.Events;
using ReactiveUI;
using ReactiveUI.Fody.Helpers;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Reactive.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;
using WPF_UI_Lightningchart.Events;

namespace WPF_UI_Lightningchart.ViewModels
{
    public class BodeBindableControlViewModel : ReactiveObject
    {

        private readonly IEventAggregator _eventAggregator;

        public Dictionary<string, PointLineSeries> AmplitudePointLineSeries { get; private set; }
        public PointLineSeriesCollection AmplitudePointLineSeriesCollection { get; private set; }

        public Dictionary<string, PointLineSeries> PhasePointLineSeries { get; private set; }
        public PointLineSeriesCollection PhasePointLineSeriesCollection { get; private set; }


        [Reactive] public SensorViewModel firstSensorViewModel { get; private set; }
        public ObservableCollection<KeyValuePair<string, SensorViewModel>> SensorViewModels { get; private set; }

        public BodeBindableControlViewModel(IEventAggregator eventAggregator)
        {
            
            AmplitudePointLineSeries = new Dictionary<string, PointLineSeries>();
            AmplitudePointLineSeriesCollection = new PointLineSeriesCollection();
            PhasePointLineSeries = new Dictionary<string, PointLineSeries>();
            PhasePointLineSeriesCollection = new  PointLineSeriesCollection();
            _eventAggregator = eventAggregator;
            _eventAggregator.GetEvent<SeriesAddedEvent>().Subscribe(OnOtherControlSeriesAdded);
            SensorViewModels = new ObservableCollection<KeyValuePair<string, SensorViewModel>>();
            SensorViewModels.CollectionChanged += (sender, args) => UpdateFirstSensorViewModel();
        }

        private void UpdateFirstSensorViewModel()
        {
            if (SensorViewModels.Count > 0)
            {
                firstSensorViewModel = SensorViewModels
                    .Select(pair => pair.Value)
                    .OrderByDescending(vm => vm.LatestDataPoint?.Speed ?? double.MinValue)
                    .FirstOrDefault();
            }
            else
            {
                firstSensorViewModel = null;
            }
        }

        public void RemoveSensorViewModel(string key)
        {
            var item = SensorViewModels.FirstOrDefault(kv => kv.Key == key);
            if (!item.Equals(default(KeyValuePair<string, SensorViewModel>)))
            {
                SensorViewModels.Remove(item);
            }
        }


        public void AddSeriesToChart(string name, string type, PointLineSeries pointLineSeries)
        {
            if (type == "AmplitudeBode")
            {
                AmplitudePointLineSeries[name] = pointLineSeries;
                AmplitudePointLineSeriesCollection.Add(AmplitudePointLineSeries[name]);
            }
            else if (type == "PhaseBode")
            {
                PhasePointLineSeries[name] = pointLineSeries;
                PhasePointLineSeriesCollection.Add(PhasePointLineSeries[name]);
            }
        }

        public void OnSeriesAdded(SensorViewModel sensorData)
        {
            if (!AmplitudePointLineSeries.ContainsKey(sensorData.SensorName) && !PhasePointLineSeries.ContainsKey(sensorData.SensorName))
            {
                _eventAggregator.GetEvent<SeriesAddedEvent>().Publish((sensorData.SensorName,"Bode"));
                AddSeriesToChart(sensorData.SensorName, "AmplitudeBode", sensorData.AmpPhaProcessor.AmplitudeSeries);
                AddSeriesToChart(sensorData.SensorName, "PhaseBode", sensorData.AmpPhaProcessor.PhaseSeries);
                SensorViewModels.Add(new KeyValuePair<string,SensorViewModel>(sensorData.SensorName, sensorData));
            }
        }
        private void OnOtherControlSeriesAdded((string sensorName, string type)type)
        {
            if (type.type == "Bode"  && AmplitudePointLineSeries.ContainsKey(type.sensorName))
            {
                var amplitudeSeries = AmplitudePointLineSeriesCollection.FirstOrDefault(x => x.Title.Text == type.sensorName);
                
                if (amplitudeSeries != null) AmplitudePointLineSeriesCollection.Remove(amplitudeSeries);

                var phaseSeries = PhasePointLineSeriesCollection.FirstOrDefault(x => x.Title.Text == type.sensorName);
                if (phaseSeries != null) PhasePointLineSeriesCollection.Remove(phaseSeries);

                AmplitudePointLineSeries.Remove(type.sensorName);
                PhasePointLineSeries.Remove(type.sensorName);

                RemoveSensorViewModel(type.sensorName);
            }
        }


    }
}
